package com.ruoyi.framework.web.service;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.File;
import java.util.Date;
import java.util.Properties;

/**
 * @author mezo
 */
@Component
public class SysEmailService {

    private final Logger logger = LoggerFactory.getLogger(SysEmailService.class);

    private final static Integer DEFAULT_SEND_PORT = 25;
    private final static Integer DEFAULT_SEND_SSL_PORT = 465;
    private final static String DEFAULT_SEND_PROTOCOL = "smtp";
    private final static String STRING_SEPARATOR = ",";
    private final static String CHARSET_UTF8 = "UTF-8";
    private final static String CHARSET_GBK = "GBK";
    private final static String FILE_ENCODING = "B";
    @Resource
    private JavaMailSender javaMailSender;

    /**
     * 发送验证码
     * @param to
     * @param subject
     * @param content
     */
    public void verifyCode(String to, String subject, String content){
        systemMail(to, null, null,subject,content,null,null,null);
    }

    /**
     * 发送通知邮件
     *
     * @param to
     * @param cc
     * @param bcc
     * @param subject
     * @param content
     * @param images
     * @param files
     */
    public void sendNotice(String to, String cc, String bcc, String subject, String content, String images, String files){
        systemMail(to, cc, bcc,subject,content,images,files,null);
    }

    /**
     * 发送系统邮件
     *
     * 其中各个参数含义如下:
     * toEmail： 发送到对应的邮箱
     * ccEmail：抄送到对应的邮箱
     * bccEmail：秘密抄送到对应邮箱
     * subject：邮件主题
     * text： 字符文本,可以是html元素文本
     * files：附件
     * 在这个基础上，其实我们还是有额外的参数需要设置的，可以定义成全局
     * username： 用于发送邮件的邮箱账号
     * password： 用于发送邮件的邮箱密码
     * host：发送邮件的主机
     * port：发送邮件的端口
     * protocol：发送邮件的协议，默认值是：smtp
     * defaultEncoding：发送邮件的字符集，默认使用UTF-8
     */
    private void systemMail(String to, String cc, String bcc, String subject, String content, String images, String files, Date sendDate) {
        try {
            final MimeMessage mimeMailMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMailMessage, true);
            mimeMessageHelper.setFrom(RuoYiConfig.getMailUser());
            mimeMessageHelper.setValidateAddresses(true);
            mimeMessageHelper.setTo(to.split(STRING_SEPARATOR));
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(content);
            if (StringUtils.isNotEmpty(cc)) {
                mimeMessageHelper.setCc(cc.split(STRING_SEPARATOR));
            }
            if (StringUtils.isNotEmpty(bcc)) {
                mimeMessageHelper.setBcc(bcc.split(STRING_SEPARATOR));
            }
            if (StringUtils.isNotEmpty(images)) {
                for (String fileName : images.split(STRING_SEPARATOR)) {
                    // 添加附件，使用完整的文件名（包括后缀名）
                    mimeMessageHelper.addInline(fileName, new File(RuoYiConfig.getDownloadPath() + fileName));
                }
            }
            if (StringUtils.isNotEmpty(files)) {
                for (String fileName : files.split(STRING_SEPARATOR)) {
                    // 添加附件，使用完整的文件名（包括后缀名）
                    mimeMessageHelper.addAttachment(StringUtils.substring(fileName, StringUtils.lastIndexOf(fileName, "/") + 1), new File(RuoYiConfig.getDownloadPath() + fileName));
                }
            }
            if (ObjectUtils.isNotEmpty(sendDate)) {
                mimeMessageHelper.setSentDate(sendDate);
            }
            javaMailSender.send(mimeMailMessage);
        } catch (Exception e) {
            logger.error("发送邮件异常:{}", e);
        }
    }

    /**
     *
     * @param username 发送方
     * @param password 授权码
     * @param to 接收方
     * @param cc 抄送方
     * @param bcc 密抄方
     * @param subject 主题
     * @param content 内容
     * @param images 内嵌图片
     * @param files 附件
     */
    public void sendMail(String username, String password, String to, String cc, String bcc, String subject, String content, String images, String files) {
        final JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setUsername(username);
        javaMailSender.setPassword(password);
        String host = "." + StringUtils.substring(username, StringUtils.lastIndexOf(username, "@"));
        javaMailSender.setHost(DEFAULT_SEND_PROTOCOL + host);
        javaMailSender.setPort(DEFAULT_SEND_PORT);
        javaMailSender.setProtocol(DEFAULT_SEND_PROTOCOL);
        javaMailSender.setDefaultEncoding(CHARSET_UTF8);
        final MimeMessage mimeMessage = getMimeMessage(javaMailSender, username, to, cc, bcc, subject, content, images, files);
        javaMailSender.send(mimeMessage);
    }

    /**
     *
     * @param username 发送方
     * @param password 授权码
     * @param to 接收方
     * @param cc 抄送方
     * @param bcc 密抄方
     * @param subject 主题
     * @param content 内容
     * @param images 内嵌图片
     * @param files 附件
     */
    public void sendSslMail(String username, String password, String to, String cc, String bcc, String subject, String content, String images, String files) {
        final JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setUsername(username);
        javaMailSender.setPassword(password);
        String host = "." + StringUtils.substring(username, StringUtils.lastIndexOf(username, "@"));
        javaMailSender.setHost(DEFAULT_SEND_PROTOCOL + host);
        javaMailSender.setPort(DEFAULT_SEND_SSL_PORT);
        final Properties mailProperties = new Properties();
        mailProperties.put("mail.debug", "true");
        mailProperties.put("mail.smtp.auth", "true");
        mailProperties.put("mail.smtp.starttls.enable", "true");
        javaMailSender.setJavaMailProperties(mailProperties);
        javaMailSender.setProtocol(DEFAULT_SEND_PROTOCOL);
        javaMailSender.setDefaultEncoding(CHARSET_UTF8);
        final MimeMessage mimeMessage = getMimeMessage(javaMailSender, username, to, cc, bcc, subject, content, images, files);
        javaMailSender.send(mimeMessage);
    }

    private MimeMessage getMimeMessage(JavaMailSenderImpl javaMailSender, String from, String to, String cc, String bcc, String subject, String content, String images, String files) {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, CHARSET_UTF8);
            mimeMessageHelper.setFrom(from);
            mimeMessageHelper.setTo(to.split(STRING_SEPARATOR));
            if (StringUtils.isNotEmpty(cc)) {
                mimeMessageHelper.setCc(cc.split(STRING_SEPARATOR));
            }
            if (StringUtils.isNotEmpty(bcc)) {
                mimeMessageHelper.setBcc(bcc.split(STRING_SEPARATOR));
            }
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(content, true);
            if (StringUtils.isNotEmpty(images)) {
                for (String img : images.split(STRING_SEPARATOR)) {
                    String fileName = StringUtils.substring(img, StringUtils.lastIndexOf(img, "/"));
                    mimeMessageHelper.addInline(MimeUtility.encodeText(fileName, CHARSET_GBK, FILE_ENCODING), new File(RuoYiConfig.getDownloadPath() + img));
                }
            }
            if (StringUtils.isNotEmpty(files)) {
                for (String file : files.split(STRING_SEPARATOR)) {
                    String fileName = StringUtils.substring(file, StringUtils.lastIndexOf(file, "/"));
                    mimeMessageHelper.addAttachment(MimeUtility.encodeText(fileName, CHARSET_GBK, FILE_ENCODING), new File(RuoYiConfig.getDownloadPath() + file));
                }
            }
        } catch (Exception e) {
            logger.error("封装邮件主体异常:{}", e);
        }
        return mimeMessage;
    }
}
